package com.example.opengl_test00;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.app.Activity;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.os.SystemClock;
import android.util.Log;

public class SpaceRenderer implements Renderer {
	
	private Context mContext;
	
	public SpaceRenderer(Context context)
	{
		mContext = context;
		
		Vertor3f a = new Vertor3f(10.0f, 0.0f, 0.0f);
		Vertor3f b = new Vertor3f(0.0f, 10.0f, 0.0f);
		Vertor3f c = new Vertor3f(0.0f, 0.0f, 10.0f);
		
		{
			ByteBuffer byteBuf = ByteBuffer.allocateDirect(6 * 3 * 4);
			byteBuf.order(ByteOrder.nativeOrder());
			vertexBuf = byteBuf.asFloatBuffer();
			vertexBuf.put(new float[] { 0.0f, 0.0f, 0.0f });
			vertexBuf.put(a.toArray());
			vertexBuf.put(new float[] { 0.0f, 0.0f, 0.0f });
			vertexBuf.put(b.toArray());
			vertexBuf.put(new float[] { 0.0f, 0.0f, 0.0f });
			vertexBuf.put(c.toArray());
			vertexBuf.position(0);
		}
		
		{
			ByteBuffer byteBuf = ByteBuffer.allocateDirect(6 * 4 * 4);
			byteBuf.order(ByteOrder.nativeOrder());
			colorBuf = byteBuf.asFloatBuffer();
			colorBuf.put(new float[] { 1.0f, 0.0f, 0.0f, 0.0f });
			colorBuf.put(new float[] { 1.0f, 0.0f, 0.0f, 0.0f });
			colorBuf.put(new float[] { 0.0f, 1.0f, 0.0f, 0.0f });
			colorBuf.put(new float[] { 0.0f, 1.0f, 0.0f, 0.0f });
			colorBuf.put(new float[] { 0.0f, 0.0f, 1.0f, 0.0f });
			colorBuf.put(new float[] { 0.0f, 0.0f, 1.0f, 0.0f });
			colorBuf.position(0);
		}
		
		mSphere = new Sphere(10.0f, 16);
		mBox = new Box(20.0f, 20.0f, 20.0f);
	}

	@Override
	public void onDrawFrame(GL10 gl) {	
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		float time = SystemClock.uptimeMillis() / 1000.0f;
		float angle = time * 0.8f;
		
		final float _23_26 = 23.0f + 26.0f / 60.0f;
		// camera pose
		float eyeX = 0.0f; // (float)Math.cos(angle) * 40.0f;
		float eyeY = 0.0f;
		float eyeZ = 40.0f; // (float)Math.sin(angle) * 40.0f;
		float centerX = 0.0f, centerY = 0.0f, centerZ = 0.0f;
		float upX = 0.0f, upY = 1.0f, upZ = 0.0f;
		
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
		
		GLU.gluLookAt(gl, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
		
		gl.glPushMatrix();
		
//		gl.glRotatef(angle / (float)Math.PI * 180.0f,  0.0f, 0.0f, 1.0f);
//		gl.glRotatef(angle / (float)Math.PI * 180.0f,  0.0f, 1.0f, 0.0f);
		
//		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuf);
//		gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuf);
//		
//		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//		
//		gl.glDrawArrays(GL10.GL_LINES, 0, 6);
//		
//		gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
//		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		
		mSphere.draw(gl);
		
//		mBox.draw(gl);
		
		gl.glPopMatrix();
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		Log.d("SpaceRenderer", "onSurfaceChanged");
		gl.glViewport(0, 0, width, height);
		
		float ratio = (float)width / (float)height;
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glFrustumf(-ratio, ratio, -1.0f, 1.0f, 1.0f, 100.0f);
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {		
		Log.d("SpaceRenderer", "onSurfaceCreated");
		/*
         * By default, OpenGL enables features that improve quality
         * but reduce performance. One might want to tweak that
         * especially on software renderer.
         */
		gl.glDisable(GL10.GL_DITHER);

        /*
         * Some one-time OpenGL initialization can be made here
         * probably based on features of this particular context
         */
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
		
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
             
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glShadeModel(GL10.GL_SMOOTH);
		gl.glEnable(GL10.GL_DEPTH_TEST);
         
		/*
		 * lighting
		 */
		FloatBuffer ambient = FloatBuffer.wrap( new float[] { 0.0f, 0.0f, 0.0f, 1.0f } );
		FloatBuffer diffuse = FloatBuffer.wrap( new float[] { 1.0f, 1.0f, 1.0f, 1.0f } );
		FloatBuffer specular = FloatBuffer.wrap( new float[] { 1.0f, 1.0f, 1.0f, 1.0f } );
		FloatBuffer position0 = FloatBuffer.wrap( new float[] { 20.0f, 20.0f, 20.0f } );
		FloatBuffer position1 = FloatBuffer.wrap( new float[] {  0.0f, 20.0f,  0.0f } );
		
		gl.glEnable(GL10.GL_LIGHTING);
		
//		gl.glLightModel(GL10.GL_LIGHT_MODEL_COLOR_CONTROL, GL10.GL_SEPARATE_SPECULAR_COLOR);
//		gl.glDepthFunc(GL10.GL_ALWAYS); 
//		gl.glEnable(GL10.GL_COLOR_SUM);
		
		gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, ambient);

		gl.glEnable(GL10.GL_LIGHT0);
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, position0);	
//		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambient);

//		gl.glEnable(GL10.GL_LIGHT1);
//		gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, position0);
 		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuse);
		
//		gl.glEnable(GL10.GL_LIGHT2);
//		gl.glLightfv(GL10.GL_LIGHT2, GL10.GL_POSITION, position0);
 		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specular);
         
		mSphere.createTexture(gl, mContext.getResources().openRawResource(R.drawable.earthmap1k));
	}

	private FloatBuffer vertexBuf;
	private FloatBuffer colorBuf;
	private Sphere mSphere;
	private Box mBox;
}
